package com.lagou.edu.factory.parser;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @Author: ZLY
 * @Date: 2020/10/14 23:42
 * @Description:
 */
public class ClassPathBeanDefinitionScanner {
    public Set<Class<?>> scan(String basePackage) throws Exception {
        return getClasses(basePackage);
    }

    /**
     * 从basePackage下获取所有的Class
     * @param basePackage
     * @return
     * @throws Exception
     */
    public Set<Class<?>> getClasses(String basePackage) throws Exception {
        // 第一个class类的集合
        //List<Class<?>> classes = new ArrayList<Class<?>>();
        Set<Class<?>> classes = new HashSet<>();
        // 获取包的名字 并进行替换
        String packageDirName = basePackage.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的things
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            // 循环迭代下去
            while (dirs.hasMoreElements()) {
                // 获取下一个元素
                URL url = dirs.nextElement();
                // 得到协议的名称
                String protocol = url.getProtocol();
                // 如果是以文件的形式保存在服务器上
                if ("file".equals(protocol)) {
                    // 获取包的物理路径
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    // 以文件的方式扫描整个包下的文件 并添加到集合中
                    addClass(classes, filePath, basePackage);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return classes;
    }
    private void addClass(Set<Class<?>> classes, String filePath, String packageName) throws Exception {
        File[] files = new File(filePath).listFiles(file -> (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory());
        assert files != null;
        for (File file : files) {
            String fileName = file.getName();
            if (file.isFile()) {
                String classsName = fileName.substring(0, fileName.lastIndexOf("."));
                if (!packageName.isEmpty()) {
                    classsName = packageName + "." + classsName;
                }
                classes.add(Class.forName(classsName));
            }
            if(file.listFiles()!=null && file.listFiles().length > 0){
                //递归进行包扫描
                addClass(classes,filePath+"/"+fileName,packageName+"."+fileName);
            }

        }
    }

}
